#include "PrivateBusSlave.h"
#include "ModBusToPrivateBus_CRC.h"
bool BusState= false;//总线状态：是否在线
uint8_t PrivateBus_Slave_ID=0x55;//模块的从机地址
//uint16_t Random;//随机数
//bool ReSendFlag;//发送失败（中间被主机发送打断），是否重新发送
//uint8_t ReceiveMsgID;//消息ID
//uint16_t ModBus_CPT[8]={0};//串行链路诊断计数器
/**
  * @bried  从机初始化
  * @note   错误原因：超时，总线设备过多，地址占用过多
  * @param  None
  * @retval 初始化失败的错误码
  */
PB_ERR PrivateBus_Slave_Init(void){
    //根据总线模拟电平获取从机地址
    float level=PB_Get_Bus_Level();

    BusState=level>=0.6;//总线根据连接状态
    if (BusState){
        PrivateBus_Slave_ID=(uint8_t)((3.35-level)/0.6)+1;
        PB_Set_Bus_Led(PB_LED_STATE_ON);
    } else{
        PB_Set_Bus_Led(PB_LED_STATE_OFF);//未挂在到总线
    }
    PB_Set_Mcu_Led(PB_LED_STATE_ON);//MCU启动成功
    return PB_ERR_NONE;
}
/**
  * @bried  私有协议从机接收消息处理
  * @note   None
  * @param  None
  * @retval None
  */
void PrivateBus_Slave_DealWith(uint8_t* _data,uint16_t _len){
    if (_data[0]!=0x00&&_data[0]!=PrivateBus_Slave_ID)return;//不是该模块的消息
    //校验CRC
    uint8_t CRC_bit_H,CRC_bit_L;
    PB_Get_CRC(_data,_len-2,&CRC_bit_L,&CRC_bit_H);
    //CRC校验失败，直接返回。
    if (CRC_bit_L!=_data[_len-2]||CRC_bit_H!=_data[_len-1])return;
    //填充消息头
    PrivateBus_Uart_Tx_Buffer[0]=PrivateBus_Slave_ID;//从机地址
    PrivateBus_Uart_Tx_Buffer[1]=_data[1];//功能码

    uint16_t reg_count=0;
    PB_Reg_Coil_State Coil_State=PB_Reg_Coil_State_Off;
    //设置返回数据大小，确定的返回消息值，等消息
    switch (PrivateBus_Uart_Tx_Buffer[1]){
        case 0x01://读取寄存器当前状态
        case 0x02://读取离散输入寄存器状态
            reg_count=__2U8TU16(_data[4],_data[5]);
            PrivateBus_Uart_Tx_Buffer[2]=(reg_count)/8;
            if (reg_count%8!=0)PrivateBus_Uart_Tx_Buffer[2]++;
            //设置消息长度
            PrivateBus_Uart_Tx_Buffer_Len=PrivateBus_Uart_Tx_Buffer[2]+5;
            break;
        case 0x03:
        case 0x04:
            reg_count=__2U8TU16(_data[4],_data[5]);
            PrivateBus_Uart_Tx_Buffer[2]=reg_count*2;
            //设置消息长度
            PrivateBus_Uart_Tx_Buffer_Len=PrivateBus_Uart_Tx_Buffer[2]+5;
            break;
        case 0x05:
				Coil_State=((__2U8TU16(_data[4],_data[5]))==0xFF00)?PB_Reg_Coil_State_On:PB_Reg_Coil_State_Off;
        case 0x06:
            PrivateBus_Uart_Tx_Buffer_Len=9;//不需要CRC校验和消息编号添加
            memcpy(PrivateBus_Uart_Tx_Buffer,_data,PrivateBus_Uart_Tx_Buffer_Len);
            break;
//        case 0x08:
//            PrivateBus_Uart_Tx_Buffer_Len=8;
//            PrivateBus_Uart_Tx_Buffer[2]=_data[2];
//            PrivateBus_Uart_Tx_Buffer[3]=_data[3];
//            break;
        case 0x10://连续写，只需要重新生成CRC消息
        case 0x0F:
            reg_count=__2U8TU16(_data[4],_data[5]);
            PrivateBus_Uart_Tx_Buffer_Len=8;
            memcpy(PrivateBus_Uart_Tx_Buffer,_data,PrivateBus_Uart_Tx_Buffer_Len-2);
            break;
        //拓展功能
//        case 0xFC:PB_Reboot(true);return;//恢复默认状态
//        case 0xFD:PB_Reboot(false);return;//设置设备重启
				case 0x41:PrivateBus_Uart_Tx_Buffer_Len=8;break;
        default:
            break;
    }
    //调用接口，寄存器操作
    switch (PrivateBus_Uart_Tx_Buffer[1]) {
        case 0x01:PB_Port_01(__2U8TU16(_data[2],_data[3]),reg_count,&(PrivateBus_Uart_Tx_Buffer[3]));break;
        case 0x02:PB_Port_02(__2U8TU16(_data[2],_data[3]),reg_count,&(PrivateBus_Uart_Tx_Buffer[3]));break;
        case 0x03:PB_Port_03(__2U8TU16(_data[2],_data[3]),reg_count,&(PrivateBus_Uart_Tx_Buffer[3]));break;
        case 0x04:PB_Port_04(__2U8TU16(_data[2],_data[3]),reg_count,&(PrivateBus_Uart_Tx_Buffer[3]));break;
        case 0x05:PB_Port_05(__2U8TU16(_data[2],_data[3]),Coil_State);goto PrivateBus_Slave_DealWith_End_No_CRC;
        case 0x06:PB_Port_06(__2U8TU16(_data[2],_data[3]),(__2U8TU16(_data[4],_data[5])));goto PrivateBus_Slave_DealWith_End_No_CRC;
//        case 0x08:PB_Port_08(__2U8TU16(_data[2],_data[3]),__2U8TU16(_data[4],_data[5]),&(PrivateBus_Uart_Tx_Buffer[4]));
        case 0x10:PB_Port_10(__2U8TU16(_data[2],_data[3]),reg_count,&(_data[7]));break;
        case 0x0F:PB_Port_0F(__2U8TU16(_data[2],_data[3]),reg_count,&(_data[7]));break;
        case 0x41:PB_Get_Reg(&(PrivateBus_Uart_Tx_Buffer[2]));break;//获取寄存器状态 65-72 100-110命令字为用户定义范围。
        default:
            break;
    }
    //添加CRC校验
    PB_Get_CRC(PrivateBus_Uart_Tx_Buffer,PrivateBus_Uart_Tx_Buffer_Len-2,&CRC_bit_L,&CRC_bit_H);
    PrivateBus_Uart_Tx_Buffer[PrivateBus_Uart_Tx_Buffer_Len-2]=CRC_bit_L;
    PrivateBus_Uart_Tx_Buffer[PrivateBus_Uart_Tx_Buffer_Len-1]=CRC_bit_H;
PrivateBus_Slave_DealWith_End_No_CRC:
    //发送消息
    PB_Send_Date(PrivateBus_Uart_Tx_Buffer,PrivateBus_Uart_Tx_Buffer_Len);
}

/**
  * @bried  获取该模块的寄存器长度信息
  * @note   None
  * @param  None
  * @retval None
  */
void PB_Get_Reg(uint8_t* reg_num){
    reg_num[0]=PrivateBus_Memory_Lens[0];
    reg_num[1]=PrivateBus_Memory_Lens[1];
    reg_num[2]=PrivateBus_Memory_Lens[2];
    reg_num[3]=PrivateBus_Memory_Lens[3];
}
